#include "ulist.h"
#include <assert.h>

struct listNode{
	listItemType Item;
	ptrType Next;
};

Ulist::Ulist(): size(0), Head(nullptr){}

Ulist::Ulist(const Ulist &L): size(L.size)
{
	if(L.Head == nullptr)
		Head = nullptr;
	else
	{
		Head = new listNode;
		assert(Head!=nullptr);
		Head->Item = L.Head->Item;
		ptrType Newptr = Head;
		for(ptrType curr = L.Head->Next; curr != nullptr; curr = curr->Next)
		{
			Newptr->Next = new listNode;
			assert(Newptr->Next);
			Newptr = Newptr->Next;
			Newptr->Item = curr->Item;
		}
		Newptr->Next = nullptr;
	}
}

Ulist::~Ulist()
{
	bool Success;
	while(!empty())
		eraser(0, Success);
}

bool Ulist::empty()const
{
	return size == 0;
}

int Ulist::length()const
{
	return size;
}

ptrType Ulist::PtrTo(int Position)const
{
	if(Position < 0 || Position >= size )
		return nullptr;

	ptrType curr = Head;
	for(int i = 0; i < Position; i++)
		curr = curr->Next;

	return curr;
}

void Ulist::insert(int NewPosition, listItemType NewItem, bool& Success)
{
	Success = ( NewPosition >= 0 && NewPosition <= size );
	if(!Success) return ;

	ptrType Newptr = new listNode;
	Success = (Newptr != nullptr);
	if(!Success) return ;

	Newptr->Item = NewItem;

	if(NewPosition == 0)
	{
		Newptr->Next = Head;
		Head = Newptr;
	}
	else
	{
		ptrType pt = PtrTo(NewPosition - 1);
		Newptr->Next = pt->Next;
		pt->Next = Newptr;
	}

	size++;

	return ;
}

void Ulist::push_back(listItemType NewItem, bool& Success)
{
	if(Head == nullptr)
	{
		Head = new listNode;
		Success = (Head != nullptr);
		if(!Success)return ;

		Head->Item = NewItem;
		Head->Next = nullptr;
	}
	else
	{
		ptrType pt = PtrTo(size-1);
		ptrType Newptr = new listNode;
		Success = (Newptr != nullptr);
		if(!Success)return ;

		Newptr->Item = NewItem;
		pt->Next = Newptr;
		Newptr->Next = nullptr;
	}

	return ;
}

void Ulist::eraser(int Position, bool& Success)
{
	Success = ( Position >= 0 && Position < size );
	if(!Success)return ;

	ptrType temp;
	size--;
	if(Position == 0)
	{
		temp = Head;
		Head = Head->Next;
	}
	else
	{
		ptrType pt = PtrTo(Position - 1);
		temp = pt->Next;
		pt->Next = temp->Next;
	}

	delete temp;
	temp = nullptr;

	return ;
}

listItemType& Ulist::operator[](const int Position)
{
	//if(Position < 0 || Position >= size)
	//	return nullptr;

	ptrType pt = PtrTo(Position);

	return pt->Item;
}
